<template>
  <div class="content-block">
    <div class="content-main">
      <div class="content-title">
        <div class="title-text-dot">角色列表</div>
        <div class="title-handle">
          <div class="handel-item">
            <el-button type="primary" size="mini" @click="handleAdd"
              >新 增</el-button
            >
          </div>
          <div class="handel-item">
            <el-button type="primary" size="mini" @click="handleSearch"
              >查 询</el-button
            >
          </div>
          <div class="handel-item">
            <el-input
              v-model="roleName"
              size="mini"
              type="text"
              placeholder="角色名"
            ></el-input>
          </div>
        </div>
      </div>
      <el-table
        :data="roleList"
        border
        size="mini"
        height="calc(100vh - 230px)"
        v-loading="tableLoading"
        style="width: 100%"
      >
        <el-table-column
          type="index"
          label="序号"
          :index="indexMethod"
          align="center"
        ></el-table-column>
        <el-table-column label="角色名" prop="roleName"></el-table-column>
        <el-table-column
          label="角色说明"
          show-overflow-tooltip
          prop="remark"
        ></el-table-column>
        <el-table-column label="操作" align="center" width="220">
          <template slot-scope="scope">
            <el-button
              size="mini"
              type="text"
              title="编辑"
              class="text-blue"
              @click="handleEdit(scope.row)"
              >编辑</el-button
            >
            <el-button
              size="mini"
              type="text"
              title="用户列表"
              class="text-blue"
              @click="handleUser(scope.row)"
              >用户列表</el-button
            >
            <el-button
              size="mini"
              type="text"
              title="菜单权限"
              class="text-blue"
              @click="handleMenu(scope.row)"
              >菜单权限</el-button
            >
            <el-button
              size="mini"
              type="text"
              title="删除"
              class="text-red"
              @click="handleDelete(scope.row)"
              >删除</el-button
            >
          </template>
        </el-table-column>
      </el-table>
      <el-pagination
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="current"
        :page-size="pageSize"
        :page-sizes="[5, 10, 20, 50]"
        layout="total, sizes, prev, pager, next"
        :total="total"
      ></el-pagination>
      <!--操作弹窗-->
      <el-dialog
        :title="handleTitle"
        :close-on-click-modal="false"
        :visible.sync="handleVisible"
        width="35%"
        center
      >
        <el-form
          ref="roleForm"
          :model="roleForm"
          :rules="roleFormRule"
          status-icon
          label-width="90px"
          size="small"
        >
          <el-form-item label="角色名" prop="roleName">
            <el-row>
              <el-col :span="24">
                <el-input v-model="roleForm.roleName" type="text"></el-input>
              </el-col>
            </el-row>
          </el-form-item>
          <el-form-item label="说明" prop="remark">
            <el-row>
              <el-col :span="24">
                <el-input v-model="roleForm.remark" type="text"></el-input>
              </el-col>
            </el-row>
          </el-form-item>
        </el-form>
        <div slot="footer" class="dialog-footer">
          <el-button @click="handleVisible = false" size="mini"
            >取 消</el-button
          >
          <el-button type="primary" @click="handleSave" size="mini"
            >保 存</el-button
          >
        </div>
      </el-dialog>
      <!-- 删除弹窗 -->
      <el-dialog
        :close-on-click-modal="false"
        title="删除角色"
        :visible.sync="delVisible"
        width="260px"
        center
      >
        <div class="del-dialog-cnt">删除不可恢复，是否确定删除？</div>
        <span slot="footer" class="dialog-footer">
          <el-button size="mini" @click="delVisible = false">取 消</el-button>
          <el-button size="mini" type="danger" @click="deleteRow"
            >确 定</el-button
          >
        </span>
      </el-dialog>
      <!--用户列表-->
      <el-dialog
        :close-on-click-modal="false"
        title="绑定用户"
        :visible.sync="userShow"
        width="40%"
        center
      >
        <el-table
          :data="userAllList"
          border
          ref="userTable"
          size="mini"
          v-loading="subLoading"
          @selection-change="selectionChange"
          style="width: 100%"
        >
          <el-table-column type="selection" width="55"></el-table-column>
          <el-table-column
            label="用户名"
            prop="username"
            width="150"
            align="center"
          ></el-table-column>
          <el-table-column
            label="姓名"
            width="150"
            align="center"
            prop="name"
          ></el-table-column>
          <el-table-column
            label="手机号"
            width="150"
            align="center"
            prop="mobile"
          ></el-table-column>
          <el-table-column
            label="部门名称"
            show-overflow-tooltip
            min-width="200"
            align="center"
            prop="deptName"
          ></el-table-column>
        </el-table>
        <el-pagination
          @size-change="handleSubSize"
          @current-change="handleSubCurrent"
          :current-page="subCurrent"
          :page-size="subSize"
          :page-sizes="[5, 10, 20, 50]"
          layout="total, sizes, prev, pager, next"
          :total="subTotal"
        ></el-pagination>
        <span slot="footer" class="dialog-footer">
          <el-button size="mini" @click="userShow = false">取 消</el-button>
          <el-button size="mini" type="primary" @click="userSave"
            >确 定</el-button
          >
        </span>
      </el-dialog>
      <!--菜单树-->
      <el-dialog
        :close-on-click-modal="false"
        title="绑定菜单"
        :visible.sync="menuShow"
        width="400px"
        center
      >
        <div style="max-height: 500px;overflow-y: auto">
          <el-tree
            ref="permissionTree"
            show-checkbox
            class="tree-body"
            :default-expand-all="true"
            :data="allMenuDataList"
            node-key="menuId"
            :default-checked-keys="bindMenu.menuIds"
            :props="defaultProps"
          ></el-tree>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button size="mini" @click="menuShow = false">取 消</el-button>
          <el-button size="mini" type="primary" @click="menuSave"
            >确 定</el-button
          >
        </span>
      </el-dialog>
    </div>
  </div>
</template>

<script>
import { mapState, mapActions } from 'vuex';

export default {
  data() {
    return {
      current: 1,
      subCurrent: 1,
      pageSize: 10,
      subSize: 10,
      total: 0,
      subTotal: 0,
      roleId: '',
      roleName: '',
      tableLoading: false,
      subLoading: false,
      handleTitle: '',
      handleVisible: false,
      delVisible: false,
      userShow: false,
      menuShow: false,
      bindUser: {
        roleId: '',
        userIds: [],
      },
      bindMenu: {
        roleId: '',
        menuIds: [],
      },
      selectMenuIds:[],
      roleForm: {
        remark: '',
        roleName: '',
      },
      roleFormRule: {
        roleName: [
          { required: true, message: '请输入角色名', trigger: 'blur' },
        ],
        remark: [
          { required: true, message: '请输入角色说明', trigger: 'blur' },
        ],
      },
      defaultProps: {
        children: 'children',
        label: 'name',
      },
      idKey: 'userId',
      userMultiple: [],
    };
  },
  computed: {
    ...mapState({
      userAllList: (state) => state.roleManage.userAllList,
      roleList: (state) => state.roleManage.roleList,
      usersInRole: (state) => state.roleManage.usersInRole,
      allMenuDataList: (state) => state.menuManage.allMenuDataList,
    }),
  },
  mounted() {
    this.getData();
    this.getUser();
    this.getAllMenuList(this);
  },
  methods: {
    ...mapActions('menuManage', ['getAllMenuList']),
    ...mapActions('roleManage', [
      'getRoleList',
      'getUserList',
      'addRole',
      'editRole',
      'removeRole',
      'getUsersInRole',
      'getUserInMenu',
      'bindRoleUsers',
      'bindRoleMenus',
    ]),
    indexMethod(index) {
      return (this.current - 1) * this.pageSize + 1 + index;
    },
    getData() {
      this.tableLoading = true;
      this.getRoleList(this);
    },
    getUser() {
      this.subLoading = true;
      this.getUserList(this);
    },
    resetForm() {
      const vm = this;
      vm.roleForm = {
        remark: '',
        roleName: '',
      };
      vm.$nextTick(() => {
        vm.$refs.roleForm.clearValidate();
      });
    },
    resetUser() {
      this.userMultiple = [];
      this.bindUser = {
        roleId: '',
        userIds: [],
      };
    },
    handleSizeChange(val) {
      this.pageSize = val;
      this.getData();
    },
    handleCurrentChange(val) {
      this.current = val;
      this.getData();
    },
    handleSubSize(val) {
      this.subSize = val;
      this.changeUserCoreData();
      this.getUser();
    },
    handleSubCurrent(val) {
      this.subCurrent = val;
      this.changeUserCoreData();
      this.getUser();
    },
    handleSearch() {
      this.current = 1;
      this.getData();
    },
    handleAdd() {
      const vm = this;
      vm.resetForm();
      vm.handleVisible = true;
      vm.handleTitle = '新增角色';
    },
    handleEdit(row) {
      const vm = this;
      vm.resetForm();
      vm.handleVisible = true;
      vm.handleTitle = '编辑角色';
      vm.roleForm = { ...row };
    },
    handleDelete(row) {
      this.roleId = row.roleId;
      this.delVisible = true;
    },
    deleteRow() {
      this.removeRole(this);
    },
    handleSave() {
      const vm = this;
      vm.$refs['roleForm'].validate((valid) => {
        if (valid) {
          if (vm.handleTitle === '新增角色') {
            vm.addRole(vm);
          } else {
            vm.editRole(vm);
          }
        } else {
          return false;
        }
      });
    },
    async handleUser(row) {
      const vm = this;
      vm.resetUser();
      vm.roleId = row.roleId;
      vm.bindUser.roleId = row.roleId;
      let res = await vm.getUsersInRole(vm);
      vm.userShow = true;
      if (res.length > 0) {
        vm.bindUser.userIds = res;
      } else {
        vm.bindUser.userIds = [];
      }
      vm.setUserSelectRow();
    },
    async handleMenu(row) {
      const vm = this;
      vm.roleId = row.roleId;
      vm.bindMenu.roleId = row.roleId;
      let res = await vm.getUserInMenu(vm);
      if (res.length > 0) {
        let perIds = vm.treeToSelectArryObj(res, 'menuId', 'isBinding');
        let selectIds = [];
        perIds.forEach((item) => {
          if (!item.hasChildren) {
            selectIds.push(item.value);
          }
        });
        vm.bindMenu.menuIds = selectIds;
        vm.$nextTick(() => {
          vm.$refs.permissionTree.setCheckedKeys(vm.bindMenu.menuIds);
        });
      } else {
        vm.bindMenu.menuIds = [];
        vm.$nextTick(() => {
          vm.$refs.permissionTree.setCheckedKeys([]);
        });
      }
      vm.menuShow = true;
    },
    menuSave() {
      let checkedKeysArr = this.$refs.permissionTree
        .getCheckedKeys()
        .map(String);
      let halfCheckedKeysArr = this.$refs.permissionTree
        .getHalfCheckedKeys()
        .map(String);
      this.selectMenuIds = checkedKeysArr.concat(halfCheckedKeysArr);
      this.bindRoleMenus(this);
    },
    userSave() {
      let userIds = this.arrayIdList(this.bindUser.userIds, 'userId');
      this.bindUser.userIds = userIds;
      this.bindRoleUsers(this);
    },
    selectionChange(val) {
      const vm = this;
      vm.userMultiple = val;
      vm.changeUserCoreData();
    },
    setUserSelectRow() {
      const vm = this;
      if (!vm.bindUser.userIds || vm.bindUser.userIds.length <= 0) {
        if (vm.$refs.userTable) {
          vm.$refs.userTable.clearSelection();
        }
        return;
      }
      // 标识当前行的唯一键的名称
      let idKey = vm.idKey;
      let selectAllIds = [];
      vm.bindUser.userIds.forEach((row) => {
        selectAllIds.push(row[idKey]);
      });
      vm.$nextTick(() => {
        vm.$refs.userTable.clearSelection();
        for (let i = 0; i < vm.userAllList.length; i++) {
          if (selectAllIds.indexOf(vm.userAllList[i][idKey]) >= 0) {
            // 设置选中，记住table组件需要使用ref="table"
            vm.$refs.userTable.toggleRowSelection(vm.userAllList[i], true);
          }
        }
      });
    },
    // 记忆选择核心方法
    changeUserCoreData() {
      // 标识当前行的唯一键的名称
      let vm = this;
      let idKey = vm.idKey;
      // 如果总记忆中还没有选择的数据，那么就直接取当前页选中的数据，不需要后面一系列计算
      if (vm.bindUser.userIds.length <= 0) {
        vm.bindUser.userIds = vm.userMultiple;
        return;
      }
      // 总选择里面的key集合
      let selectAllIds = [];
      vm.bindUser.userIds.forEach((row) => {
        selectAllIds.push(row[idKey]);
      });
      let selectIds = [];
      // 获取当前页选中的id
      vm.userMultiple.forEach((row) => {
        selectIds.push(row[idKey]);
        // 如果总选择里面不包含当前页选中的数据，那么就加入到总选择集合里
        if (selectAllIds.indexOf(row[idKey]) < 0) {
          vm.bindUser.userIds.push(row);
        }
      });
      let noSelectIds = [];
      // 得到当前页没有选中的id
      vm.userAllList.forEach((row) => {
        if (selectIds.indexOf(row[idKey]) < 0) {
          noSelectIds.push(row[idKey]);
        }
      });
      noSelectIds.forEach((id) => {
        if (selectAllIds.indexOf(id) >= 0) {
          for (let i = 0; i < vm.bindUser.userIds.length; i++) {
            if (vm.bindUser.userIds[i][idKey] === id) {
              // 如果总选择中有未被选中的，那么就删除这条
              vm.bindUser.userIds.splice(i, 1);
              break;
            }
          }
        }
      });
    },
  },
};
</script>
